package me.bincker.formwork.web.modules.system.controller

import me.bincker.formwork.web.core.annotation.Permission
import me.bincker.formwork.web.core.exception.NotFoundException
import me.bincker.formwork.web.core.security.MethodSecurityMetadataSource
import me.bincker.formwork.web.modules.system.entity.Role
import me.bincker.formwork.web.modules.system.service.IRoleService
import org.springframework.data.domain.Example
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.*

@RestController
@RequestMapping("roles")
class RoleController(
        private val roleService: IRoleService,
        private val methodSecurityMetadataSource: MethodSecurityMetadataSource
) {
    @GetMapping
    @Permission("角色列表", "role.page")
    fun getPage(pageable: Pageable, role: Role?): Page<Role> {
        return if(role == null){
            roleService.findAll(pageable)
        }else{
            roleService.findAll(Example.of(role), pageable)
        }
    }

    @GetMapping("{id}")
    @Permission("角色详情", "role.detail")
    fun getOne(@PathVariable id: String) = roleService.getOne(id)

    @PostMapping
    @Permission("添加角色", "role.add")
    fun add(@RequestBody@Validated role: Role): Role{
        val allPermission = methodSecurityMetadataSource.getAllPermission()
        role.userList = null
        role.permissions = role.permissions?.filter { code-> allPermission.any { p-> p.code == code }}?.toMutableSet()
        return roleService.save(role)
    }

    @PutMapping
    @Permission("修改角色", "role.put")
    fun put(@RequestBody@Validated role: Role): Role{
        val target = roleService.findById(role.id ?: throw NotFoundException()) ?: throw NotFoundException()
        val allPermission = methodSecurityMetadataSource.getAllPermission()
        target.code = role.code
        target.permissions = role.permissions?.filter { code-> allPermission.any { p-> p.code == code }}?.toMutableSet()
        return roleService.save(target)
    }
}